package com.yk.system.controller;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yk.api.system.dto.ConfigurationDTO;
import com.yk.api.system.dto.ConfigurationRoleDTO;
import com.yk.common.core.domain.BasePageQuery;
import com.yk.common.core.domain.PageResult;
import com.yk.common.core.domain.Result;
import com.yk.common.core.utils.LoginHelper;
import com.yk.common.log.annotation.Log;
import com.yk.common.log.constant.LogConstants;
import com.yk.common.log.enums.BusinessType;
import com.yk.system.convert.ConfigurationConvert;
import com.yk.system.entity.Configuration;
import com.yk.system.entity.Group;
import com.yk.system.entity.GroupConfiguration;
import com.yk.system.service.ConfigurationRoleService;
import com.yk.system.service.ConfigurationService;
import com.yk.system.service.GroupConfigurationService;
import com.yk.system.service.GroupService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * 自组态前端控制器 yk-system
 *
 * @author lmx
 * @date 2023/11/2 10:29
 */
@Api(tags = "自组态前端控制器")
@RestController
@RequestMapping("/configuration")
@RequiredArgsConstructor
public class ConfigurationController {

    private final ConfigurationService configurationService;
    private final ConfigurationRoleService configurationRoleService;
    private final GroupConfigurationService groupConfigurationService;
    private final GroupService groupService;
    private final ConfigurationConvert configurationConvert;

    @GetMapping("/getByGroupId/{id}")
    @ApiOperation("组态表-根据场景Id查询")
    public Result<List<ConfigurationDTO>> getByGroupId(@PathVariable Long id) {
        List<ConfigurationDTO> dtoList = configurationService.getConfigurationDTOS(id, null);
        return Result.data(dtoList);
    }

    @PostMapping("/getAppByGroupId")
    @ApiOperation("小程序根据场景Id查询组态")
    public Result<List<ConfigurationDTO>> getAppByGroupId(@RequestBody ConfigurationDTO param) {
        if (0L == param.getGroupId()) {
            return Result.data(CollUtil.newArrayList());
        }
        List<ConfigurationDTO> dtoList = configurationService.getConfigurationDTOS(param.getGroupId(), param.getQ());
        return Result.data(dtoList);
    }

    @GetMapping("/getById/{id}")
    @ApiOperation("组态表-查询单个")
    public Result<ConfigurationDTO> getById(@PathVariable(value = "id") Long id) {
        Configuration configuration = configurationService.getById(id);
        ConfigurationDTO configurationDTO = configurationConvert.entity2Dto(configuration);
        LambdaQueryWrapper<GroupConfiguration> lambda = new QueryWrapper<GroupConfiguration>().lambda();
        lambda.eq(GroupConfiguration::getConfigurationId, id);
        GroupConfiguration gc = groupConfigurationService.getOne(lambda);
        if (Objects.isNull(configuration)) {
            return Result.data(configurationDTO);
        }
        Group group = groupService.getById(gc.getGroupId());
        if (Objects.nonNull(group)) {
            configurationDTO.setGroupId(group.getId());
            configurationDTO.setGroupName(group.getName());
        }
        return Result.data(configurationDTO);
    }

    @PostMapping("/save")
    @ApiOperation("组态表-新增")
    @Log(title = "组态", businessType = BusinessType.INSERT)
    public Result<Boolean> save(@RequestBody @Validated ConfigurationDTO dto) {
        if (Objects.isNull(dto.getGroupId())) {
            return Result.fail("场景不能为空");
        }
        long configurationId = IdWorker.getId();
        dto.setId(configurationId);
        configurationService.save(configurationConvert.dto2Entity(dto));
        GroupConfiguration groupConfiguration = new GroupConfiguration(dto.getGroupId(), configurationId);
        groupConfigurationService.save(groupConfiguration);
        // 组态权限
        configurationRoleService.saveDeviceRole(configurationRoleService.initConfigurationRole(configurationId));
        return Result.ok2Log(LogConstants.ADD + dto.getName());
    }

    @PostMapping("/update")
    @ApiOperation("组态表-修改")
    @Log(title = "组态", businessType = BusinessType.UPDATE)
    public Result<Boolean> updateById(@RequestBody @Validated ConfigurationDTO dto) {
        configurationService.updateById(configurationConvert.dto2Entity(dto));
        LambdaQueryWrapper<GroupConfiguration> lambda = new QueryWrapper<GroupConfiguration>().lambda();
        lambda.eq(GroupConfiguration::getConfigurationId, dto.getId());
        GroupConfiguration gc = groupConfigurationService.getOne(lambda);
        if (Objects.nonNull(gc) && !gc.getGroupId().equals(dto.getGroupId())) {
            LambdaUpdateWrapper<GroupConfiguration> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(GroupConfiguration::getConfigurationId, dto.getId());
            updateWrapper.set(GroupConfiguration::getGroupId, dto.getGroupId());
            groupConfigurationService.update(updateWrapper);
        }
        return Result.ok2Log(LogConstants.UPDATE + dto.getName());
    }

    @GetMapping("/deleteById/{id}")
    @ApiOperation("组态表-删除")
    @Log(title = "组态", businessType = BusinessType.DELETE)
    public Result<Void> deleteById(@PathVariable(value = "id") Long id) {
        Configuration configuration = configurationService.getById(id);
        if (Objects.isNull(configuration)) {
            return Result.fail("组态信息不存在");
        }
        configurationService.removeById(id);
        groupConfigurationService.remove(new LambdaQueryWrapper<GroupConfiguration>().eq(GroupConfiguration::getConfigurationId, id));
        return Result.ok2Log(LogConstants.DELETE + configuration.getName());
    }

    @PostMapping("/list")
    @ApiOperation("组态表-查询列表")
    public Result<List<ConfigurationDTO>> list(@RequestBody ConfigurationDTO param) {
        Long userId = LoginHelper.getLoginUserId();
        List<ConfigurationRoleDTO> dtoList = configurationRoleService.selectRole2Device();
        if (CollUtil.isEmpty(dtoList)) {
            return Result.ok();
        }
        List<Long> ids = dtoList.stream().map(ConfigurationRoleDTO::getId).collect(Collectors.toList());
        LambdaQueryWrapper<Configuration> lambda = new QueryWrapper<Configuration>().lambda();
        buildCondition(lambda, param);
        lambda.in(Configuration::getId, ids);
        List<Configuration> list = configurationService.list(lambda);
        if (CollUtil.isEmpty(list)) {
            return Result.data(CollUtil.newArrayList());
        }
        List<ConfigurationDTO> resultList = list.stream().map(it -> {
            ConfigurationDTO dto = configurationConvert.entity2Dto(it);
            LambdaQueryWrapper<GroupConfiguration> wrapper = new QueryWrapper<GroupConfiguration>().lambda();
            wrapper.eq(GroupConfiguration::getConfigurationId, dto.getId());
            GroupConfiguration gc = groupConfigurationService.getOne(wrapper);
            if (Objects.isNull(gc)) {
                return dto;
            }
            Group group = groupService.getById(gc.getGroupId());
            if (Objects.isNull(group)) {
                return dto;
            }
            dto.setGroupId(group.getId());
            dto.setGroupName(group.getName());
            if (userId.equals(it.getCreatedBy())) {
                dto.setEdit(Boolean.TRUE);
            } else {
                dto.setEdit(Boolean.FALSE);
            }
            dto.setValue(null);
            return dto;
        }).collect(Collectors.toList());
        return Result.data(resultList);
    }

    @PostMapping("/page")
    @ApiOperation("组态表-分页查询")
    public PageResult<Configuration> page(@RequestBody BasePageQuery<ConfigurationDTO> pageParam) {
        List<ConfigurationRoleDTO> dtoList = configurationRoleService.selectRole2Device();
        if (CollUtil.isEmpty(dtoList)) {
            return PageResult.success(CollUtil.newArrayList(), 0);
        }
        List<Long> ids = dtoList.stream().map(ConfigurationRoleDTO::getId).collect(Collectors.toList());
        ConfigurationDTO param = pageParam.getParam();
        LambdaQueryWrapper<Configuration> lambda = new QueryWrapper<Configuration>().lambda();
        buildCondition(lambda, param);
        lambda.in(Configuration::getId, ids);
        IPage<Configuration> page = configurationService.page(new Page<>(pageParam.getPageNum(), pageParam.getPageSize()), lambda);
        return PageResult.success(page.getRecords(), page.getTotal());
    }

    /**
     * 构造查询条件
     *
     * @param lambda
     * @param param
     */
    private void buildCondition(LambdaQueryWrapper<Configuration> lambda, ConfigurationDTO param) {
        //条件样例，自定义
        lambda.orderByDesc(Configuration::getCreatedAt);
    }
}